<?php

require_once("mysql.class.php");

class myDnsSql extends mySql {
    function MyDnsSql() {
		$this->mySql('localhost', 'mydns', 'utvikling1', 'mydns');
    }
}

class soa {

	var $sql;
	var $record;
	var $rr = array();
	
	function soa($origin, $db=NULL, $record=NULL) {
		if(is_a($db, 'myDnsSql')) {
			$this->sql =& $db;
		} else {
			$this->sql = new myDnsSql();
		}

		// Populate local cache of soa record
		if(is_array($record)) {
			$this->record = $record;
		} else {
			$this->record = $this->sql->getOneRow(sprintf("SELECT * FROM soa WHERE origin = '%s'", $origin));
		}

		// Populate rr object list
		if($this->getID()) {
			$rrs = $this->sql->query(sprintf("SELECT * FROM rr WHERE zone = '%s' ORDER BY type DESC,id", $this->getID()));
			while($rr = $rrs->fetch()) {
				$this->rr[] =& new rr($rr);
			}
		}
	}

	function deleteRr($index) {
		$rr =& $this->rr[$index];
		$sql = $this->sql->delete('rr', (int)$rr->getID());
		$this->sql->query($sql);
	}

	function deleteAllRr() {
		foreach($this->rr as $k=>$v) {
			$this->deleteRr($k);
		}
	}

	function deleteYourself() {
		$this->deleteAllRr();
		$sql = $this->sql->delete('soa', (int)$this->getID());
		$this->sql->query($sql);
	}
	
	// Returns ip range if zone is c-class reverse zone
	function isReverse() {
		$range = array();
		if(preg_match('/(\d+)\.(\d+)\.(\d+)\.in\-addr\.arpa\.$/', $this->getOrigin(), $range)) {
        	return sprintf('%d.%d.%d.%%', $range[3], $range[2], $range[1]);
		} else {
			return false;
		}
	}
				
	// Save soa and rr records to database
	function commit() {
		$record = $this->record;
		// Save soa record
		//var_dump($record['id']);
		if($record['id'] > 0) {
			// Update
			$id = $record['id']; unset($record['id']);
			$record['serial'] = generate_serial($record['serial']);
			$sql = $this->sql->update('soa', $record, (int)$id);
			$this->sql->query($sql);
		} else {
			// Insert
			unset($record['id']);
			$record['serial'] = generate_serial('0000000000');
			$sql = $this->sql->insert('soa', $record);
			$id = $this->sql->query($sql);
			$this->record['id'] = $id;
		}
		
		foreach($this->getRr() as $rr) {
			$record = $rr->getRecord();
			if($record['id'] > 0) {
				// Update
				$id = $record['id']; unset($record['id']);
				$sql = $this->sql->update('rr', $record, (int)$id);
			} else {
				// Insert
				unset($record['id']);
				$record['zone'] = $this->record['id'];
				$sql = $this->sql->insert('rr', $record);
			}
			//echo "rr->commit() [$sql]<br />\n";
			$this->sql->query($sql);
		}
	}

	function getID() {
		return $this->record['id'];
	}
	
	function getOrigin() {
		return $this->record['origin'];
	}
	
	function getNs() {
		return $this->record['ns'];
	}

	function getMbox() {
		return $this->record['mbox'];
	}

	function getSerial() {
		return $this->record['serial'];
	}

	function getRefresh() {
		return $this->record['refresh'];
	}

	function getRetry() {
		return $this->record['retry'];
	}

	function getExpire() {
		return $this->record['expire'];
	}

	function getMinimum() {
		return $this->record['minimum'];
	}

	function getTtl() {
		return $this->record['ttl'];
	}

	function setID($id) {
		return $this->record['id'] = $id;
	}
	
	function setOrigin($origin) {
		return $this->record['origin'] = $origin;
	}
	
	function setNs($ns) {
		return $this->record['ns'] = $ns;
	}

	function setMbox($mbox) {
		return $this->record['mbox'] = $mbox;
	}

	function setSerial($serial) {
		return $this->record['serial'] = $serial;
	}

	function setRefresh($refresh) {
		return $this->record['refresh'] = $refresh;
	}

	function setRetry($retry) {
		return $this->record['retry'] = $retry;
	}

	function setExpire($expire) {
		return $this->record['expire'] = $expire;
	}

	function setMinimum($minimum) {
		return $this->record['minimum'] = $minimum;
	}

	function setTtl($ttl) {
		return $this->record['ttl'] = $ttl;
	}
	
	function setRr(&$rr) {
		$this->rr =& $rr;
	}
	
	function addRr(&$rr) {
		return $this->rr[] =& $rr;
	}

	function &getRr() {
		return $this->rr;
	}
}

class rr {
	
	var $record;
	
	function rr ($record) {
		$this->record = $record;
	}
	
	function getRecord() {
		return $this->record;
	}

	function getID() {
		return $this->record['id'];
	}
	
	function getZone() {
		return $this->record['zone'];
	}
	
	function getName() {
		return $this->record['name'];
	}

	function getType() {
		return $this->record['type'];
	}

	function getData() {
		return $this->record['data'];
	}

	function getAux() {
		return $this->record['aux'];
	}

	function getTtl() {
		return $this->record['ttl'];
	}

	function setID($id) {
		return $this->record['id'] = $id;
	}
	
	function setZone($zone) {
		return $this->record['zone'] = $zone;
	}
	
	function setName($name) {
		return $this->record['name'] = $name;
	}

	function setType($type) {
		return $this->record['type'] = $type;
	}

	function setData($data) {
		return $this->record['data'] = $data;
	}

	function setAux($aux) {
		return $this->record['aux'] = $aux;
	}

	function setTtl($ttl) {
		return $this->record['ttl'] = $ttl;
	}
}

class soaFactory {
	function getReverseRrCollectionByIp($like) {
		$sql = new myDnsSql();
		$q = sprintf(
				"select 
					null as id, 
					null as zone,
					r.data as name,
					'PTR' as type,
					concat(r.name, '.', s.origin) as data,
					r.aux as aux,
					r.ttl as ttl
				from 
					rr r, 
					soa s 
				where 
					s.id = r.zone 
					and 
					r.type = 'A' 
					and 
					r.data like '%s' 
				order by 
					r.data",
				$like
		);
		$res = $sql->query($q);
		$rr = array();
		while($l = $res->fetch()) {
			// post-process our sql
			// remove leading . in data column, for forward records that have empty name field
			$l['data'] = preg_replace('/^\./', '', $l['data']);
			// remove everything but last digit in ip
			$l['name'] = preg_replace('/^\d+\.\d+\.\d+\./', '', $l['name']);
			$rr[] = new rr($l);
		}
		return $rr;
	}
}
